﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace blackhouse.BlackApart.Data {
    public abstract class AdoApartmentGroupDataAccess : IApartmentGroupDataAccess {

        #region IApartmentGroupDataAccess

        public abstract int SaveApartmentGroup(int id, string name, int numberOfPeople, int locationId, float areaSize);

        public abstract int DeleteApartmentGroup(int groupId);

        public abstract bool CheckExists(int groupId);

        public ApartmentGroupData GetApartmentGroup(int groupId, string language) {
            return this.ReadApartmentGroup(this.GetReaderForApartmentGroup(groupId, language));
        }

        public ApartmentGroupData[] GetApartmentGroups(string language) {
            return this.ReadApartmentGroups(this.GetReaderForApartmentGroups(language));
        }

        public Dictionary<string, object> GetApartmentGroupProperties(int apartmentGroup, string language) {
            DataTable dt = this.GetDtApartmentGroupProperties(apartmentGroup, language);
            Dictionary<string, object> data = new Dictionary<string, object>(dt.Columns.Count);
            foreach (DataColumn column in dt.Columns)
                data.Add(column.ColumnName, dt.Rows[0][column]);
            return data;
        }

        public Dictionary<string, string> GetApartmentGroupArrayProperties(int apartmentGroup, string propertyKey, string language) {
            return this.ReadApartmentGroupArrayProperties(this.GetReaderForApartmentGroupArrayProperties(apartmentGroup, propertyKey, language));
        }

        public SeoData GetApartmentGroupSeo(int apartmentGroupId, string language) {
            return this.ReadApartmentGroupSeo(this.GetReaderForApartmentGroupSeo(apartmentGroupId, language));
        }

        public ApartmentOptionFieldData[] GetApartmentGroupOptionFields(int groupId, string language) {
            return this.ReadApartmentGroupOptions(this.GetReaderForApartmentGroupOptionFields(groupId, language));
        }

        #endregion

        #region Abstracts

        protected abstract IDataReader GetReaderForApartmentGroupSeo(int groupId, string language);

        protected abstract IDataReader GetReaderForApartmentGroup(int groupId, string language);

        protected abstract IDataReader GetReaderForApartmentGroups(string language);

        protected abstract IDataReader GetReaderForApartmentGroupArrayProperties(int apartmentGroup, string property, string language);

        protected abstract IDataReader GetReaderForApartmentGroupOptionFields(int groupId, string language);

        public abstract DataTable GetDtApartmentGroupProperties(int apartmentGroup, string language);

        #endregion

        #region Methods

        private ApartmentOptionFieldData[] ReadApartmentGroupOptions(IDataReader reader) {
            List<ApartmentOptionFieldData> data = new List<ApartmentOptionFieldData>();
            while (reader.Read())
                data.Add(this.ReadApartmentGroupOptionFields(reader));
            reader.Close();
            return data.ToArray();
        }

        private ApartmentOptionFieldData ReadApartmentGroupOptionFields(IDataReader reader) {
            ApartmentOptionFieldData data = new ApartmentOptionFieldData();
            data.Description = Convert.ToString(reader["Description"]);
            data.Title = Convert.ToString(reader["Title"]);
            data.Variant = Convert.ToInt32(reader["Variant"]);
            return data;
        }

        private Dictionary<string, string> ReadApartmentGroupArrayProperties(IDataReader reader) {
            Dictionary<string, string> data = new Dictionary<string, string>();
            while (reader.Read()) {
                this.ReadApartmentGroupArrayPropertyFields(reader, data);
            }
            reader.Close();
            return data;
        }

        private void ReadApartmentGroupArrayPropertyFields(IDataReader reader, Dictionary<string, string> data) {
            string key, value;
            key = Convert.ToString(reader["Key"]);
            value = Convert.ToString(reader["Value"]);
            if (!data.ContainsKey(key))
                data.Add(key, value);
        }

        private ApartmentGroupData[] ReadApartmentGroups(IDataReader reader) {
            List<ApartmentGroupData> data = new List<ApartmentGroupData>();
            while (reader.Read())
                data.Add(this.ReadApartmentGroupFields(reader));
            reader.Close();
            return data.ToArray();
        }

        private ApartmentGroupData ReadApartmentGroup(IDataReader reader) {
            ApartmentGroupData data = default(ApartmentGroupData);
            if (reader.Read())
                data = this.ReadApartmentGroupFields(reader);
            reader.Close();
            return data;
        }

        private ApartmentGroupData ReadApartmentGroupFields(IDataReader reader) {
            ApartmentGroupData data = new ApartmentGroupData();
            data.AreaSize = Convert.ToSingle(reader["AreaSize"]);
            data.DefaultLocationId = Convert.ToInt32(reader["LocalizationId"]);
            data.Id = Convert.ToInt32(reader["Id"]);
            data.Name = Convert.ToString(reader["Name"]);
            if (!reader.IsDBNull(reader.GetOrdinal("ShortName")))
                data.ShortName = Convert.ToString(reader["ShortName"]);
            data.NumberOfPeople = Convert.ToInt32(reader["NumberOfPeople"]);
            data.Popularity = Convert.ToDouble(reader["Popularity"]);
            if (!reader.IsDBNull(reader.GetOrdinal("Stars")))
                data.Stars = Convert.ToSingle(reader["Stars"]);
            data.LastMod = Convert.ToDateTime(reader["LastMod"]);

            ApartmentPhotoData mainPhoto = new ApartmentPhotoData();
            mainPhoto.Category = Convert.ToString(reader["MainPhotoCategory"]);
            mainPhoto.Description = Convert.ToString(reader["MainPhotoDescription"]);
            mainPhoto.PhotoId = Convert.ToInt32(reader["MainPhotoId"]);
            mainPhoto.PhotoName = Convert.ToString(reader["MainPhotoName"]);
            data.MainPhoto = mainPhoto;

            return data;
        }

        private SeoData ReadApartmentGroupSeo(IDataReader reader) {
            SeoData data = default(SeoData);
            if (reader.Read())
                data = this.ReadApartmentGroupSeoFields(reader);
            reader.Close();
            return data;
        }

        private SeoData ReadApartmentGroupSeoFields(IDataReader reader) {
            SeoData data = new SeoData();
            data.PageTitle = Convert.ToString(reader["PageTitle"]);
            data.PageKeywords = Convert.ToString(reader["PageKeywords"]);
            data.PageDescription = Convert.ToString(reader["PageDescription"]);
            return data;
        }

        #endregion

    }
}
